#include <iostream>
#include <memory>

class Fruit
{
public:
    Fruit() {}
    virtual void show() = 0;
};

class Apple :public Fruit
{
public:
    Apple(){}
    virtual void show() override
    {
        std::cout << "我是一个苹果" << std::endl;
    }
};

class Banana :public Fruit
{
public:
    Banana(){}
    virtual void show() override
    {
        std::cout << "我是一个香蕉" << std::endl;
    }
};

class Animal
{
public:
    virtual void show() = 0;
};

class Goat :public Animal
{
public:
    virtual void show()
    {
        std::cout << "我是一只羊" << std::endl;
    }
};

class Dog :public Animal
{
public:
    virtual void show()
    {
        std::cout << "我是一只狗" << std::endl;
    }
};

class Factory
{
public:
    virtual std::shared_ptr<Fruit> getFruit(const std::string& name) = 0;
    virtual std::shared_ptr<Animal> getAnimal(const std::string& name) = 0;
};

class FruitFactory :public Factory
{
public:
    virtual std::shared_ptr<Animal> getAnimal(const std::string &name)
    {
        return std::shared_ptr<Animal>();
    }

    virtual std::shared_ptr<Fruit> getFruit(const std::string &name)
    {
        if (name == "苹果")
        {
            return std::make_shared<Apple>();
        }
        else if(name == "香蕉")
        {
            return std::make_shared<Banana>();
        }

        return std::shared_ptr<Fruit>();
    }
};

class AnimalFactory :public FruitFactory
{
public:
    virtual std::shared_ptr<Animal> getAnimal(const std::string &name)
    {
        if (name == "小羊")
        {
            return std::make_shared<Goat>();
        }
        else if (name == "小狗")
        {
            return std::make_shared<Dog>();
        }

        return std::shared_ptr<Animal>();
    }

    virtual std::shared_ptr<Fruit> getFruit(const std::string &name)
    {
        return std::shared_ptr<Fruit>();
    };
};

class FactoryProducer
{
public:
    static std::shared_ptr<Factory> getFactory(const std::string& name)
    {
        if (name == "动物")
        {
            return std::make_shared<AnimalFactory>();
        }
        else
        {
            return std::make_shared<FruitFactory>();
        }
    }
};

int main()
{
    std::shared_ptr<Factory> fruitfactory = FactoryProducer::getFactory("水果");
    std::shared_ptr<Fruit> fruit = fruitfactory->getFruit("苹果");
    fruit->show();
    fruit = fruitfactory->getFruit("香蕉");
    fruit->show();

    std::shared_ptr<Factory> animalfactory = FactoryProducer::getFactory("动物");
    std::shared_ptr<Animal> animal = animalfactory->getAnimal("小羊");
    animal->show();
    animal = animalfactory->getAnimal("小狗");
    // 空就不能生产了，不然段错误
    if (animal.get() == nullptr)
    {
        return 0;
    }
    animal->show();
    return 0;
}